package com.yhh.college_information_platform.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yhh.college_information_platform.common.PageResult;
import com.yhh.college_information_platform.common.ResultCode;
import com.yhh.college_information_platform.exception.BusinessException;
import com.yhh.college_information_platform.dto.CommentDTO;
import com.yhh.college_information_platform.dto.CommentQueryDTO;
import com.yhh.college_information_platform.entity.Comment;
import com.yhh.college_information_platform.entity.CommentLike;
import com.yhh.college_information_platform.entity.Resource;
import com.yhh.college_information_platform.entity.User;
import com.yhh.college_information_platform.mapper.CommentLikeMapper;
import com.yhh.college_information_platform.mapper.CommentMapper;
import com.yhh.college_information_platform.mapper.ResourceMapper;
import com.yhh.college_information_platform.mapper.UserMapper;
import com.yhh.college_information_platform.service.CommentService;
import com.yhh.college_information_platform.service.NotificationService;
import com.yhh.college_information_platform.vo.CommentVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 评论Service实现
 *
 * @author yhh
 * @date 2025-10-26
 */
@Slf4j
@Service
public class CommentServiceImpl implements CommentService {
    
    @Autowired
    private CommentMapper commentMapper;
    
    @Autowired
    private CommentLikeMapper commentLikeMapper;
    
    @Autowired
    private ResourceMapper resourceMapper;
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private NotificationService notificationService;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long publishComment(CommentDTO commentDTO, Long userId) {
        // 验证资料是否存在
        Resource resource = resourceMapper.selectById(commentDTO.getResourceId());
        if (resource == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "资料不存在");
        }
        
        // 如果是回复评论，验证父评论是否存在
        if (commentDTO.getParentId() != null && commentDTO.getParentId() > 0) {
            Comment parentComment = commentMapper.selectById(commentDTO.getParentId());
            if (parentComment == null || parentComment.getStatus() != 0) {
                throw new BusinessException(ResultCode.PARAM_ERROR, "父评论不存在或已被删除");
            }
        }
        
        // 如果是回复某个用户，验证回复的评论是否存在
        if (commentDTO.getReplyToId() != null && commentDTO.getReplyToId() > 0) {
            Comment replyToComment = commentMapper.selectById(commentDTO.getReplyToId());
            if (replyToComment == null || replyToComment.getStatus() != 0) {
                throw new BusinessException(ResultCode.PARAM_ERROR, "回复的评论不存在或已被删除");
            }
            commentDTO.setReplyToUserId(replyToComment.getUserId());
        }
        
        // 创建评论
        Comment comment = new Comment();
        comment.setResourceId(commentDTO.getResourceId());
        comment.setUserId(userId);
        comment.setParentId(commentDTO.getParentId() != null ? commentDTO.getParentId() : 0L);
        comment.setReplyToId(commentDTO.getReplyToId() != null ? commentDTO.getReplyToId() : 0L);
        comment.setReplyToUserId(commentDTO.getReplyToUserId() != null ? commentDTO.getReplyToUserId() : 0L);
        comment.setContent(commentDTO.getContent());
        comment.setLikeCount(0);
        comment.setStatus(0);
        
        int rows = commentMapper.insert(comment);
        if (rows <= 0) {
            throw new BusinessException(ResultCode.SYSTEM_ERROR, "评论发布失败");
        }
        
        // 更新资料的评论数
        resourceMapper.incrementCommentCount(commentDTO.getResourceId());
        
        // 发送通知
        User currentUser = userMapper.selectById(userId);
        if (commentDTO.getParentId() != null && commentDTO.getParentId() > 0) {
            // 这是一个回复评论，给被回复的评论者发通知
            if (commentDTO.getReplyToUserId() != null && commentDTO.getReplyToUserId() > 0) {
                notificationService.sendReplyNotification(
                    resource.getId(),
                    resource.getTitle(),
                    commentDTO.getReplyToId(),
                    commentDTO.getReplyToUserId(),
                    userId,
                    currentUser != null ? currentUser.getNickname() : "未知用户",
                    commentDTO.getContent()
                );
            }
        } else {
            // 这是一个新评论，给资料上传者发通知
            notificationService.sendCommentNotification(
                resource.getId(),
                resource.getTitle(),
                resource.getUploaderId(),
                userId,
                currentUser != null ? currentUser.getNickname() : "未知用户",
                commentDTO.getContent()
            );
        }
        
        log.info("用户{}发布评论成功，评论ID: {}", userId, comment.getId());
        return comment.getId();
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteComment(Long commentId, Long userId) {
        Comment comment = commentMapper.selectById(commentId);
        if (comment == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "评论不存在");
        }
        
        // 只能删除自己的评论
        if (!comment.getUserId().equals(userId)) {
            throw new BusinessException(ResultCode.NO_PERMISSION, "无权删除该评论");
        }
        
        // 软删除
        comment.setStatus(1);
        commentMapper.updateById(comment);
        
        // 更新资料的评论数
        resourceMapper.decrementCommentCount(comment.getResourceId());
        
        log.info("用户{}删除评论成功，评论ID: {}", userId, commentId);
    }
    
    @Override
    public PageResult<CommentVO> getCommentPage(CommentQueryDTO queryDTO, Long userId) {
        // 只查询一级评论
        LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Comment::getResourceId, queryDTO.getResourceId())
                .eq(Comment::getParentId, 0L)
                .eq(Comment::getStatus, 0);
        
        // 排序
        if ("like_count".equals(queryDTO.getOrderBy())) {
            wrapper.orderByDesc(Comment::getLikeCount);
        } else {
            wrapper.orderByDesc(Comment::getCreateTime);
        }
        
        // 分页查询
        Page<Comment> page = new Page<>(queryDTO.getCurrent(), queryDTO.getSize());
        Page<Comment> commentPage = commentMapper.selectPage(page, wrapper);
        
        // 转换为VO
        List<CommentVO> commentVOList = commentPage.getRecords().stream()
                .map(comment -> buildCommentVO(comment, userId))
                .collect(Collectors.toList());
        
        // 查询每个一级评论的回复
        for (CommentVO commentVO : commentVOList) {
            List<CommentVO> replies = getCommentReplies(commentVO.getId(), userId);
            commentVO.setReplies(replies);
            commentVO.setReplyCount(replies.size());
        }
        
        PageResult<CommentVO> result = new PageResult<>();
        result.setRecords(commentVOList);
        result.setTotal(commentPage.getTotal());
        result.setCurrent(commentPage.getCurrent());
        result.setSize(commentPage.getSize());
        result.setPages(commentPage.getPages());
        
        return result;
    }
    
    /**
     * 获取评论的回复列表
     */
    private List<CommentVO> getCommentReplies(Long parentId, Long userId) {
        LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Comment::getParentId, parentId)
                .eq(Comment::getStatus, 0)
                .orderByAsc(Comment::getCreateTime);
        
        List<Comment> replies = commentMapper.selectList(wrapper);
        
        return replies.stream()
                .map(reply -> buildCommentVO(reply, userId))
                .collect(Collectors.toList());
    }
    
    /**
     * 构建评论VO
     */
    private CommentVO buildCommentVO(Comment comment, Long userId) {
        CommentVO vo = BeanUtil.copyProperties(comment, CommentVO.class);
        
        // 查询评论用户信息
        User user = userMapper.selectById(comment.getUserId());
        if (user != null) {
            vo.setUserName(user.getNickname() != null ? user.getNickname() : user.getStudentId());
            vo.setUserAvatar(user.getAvatar());
        }
        
        // 如果是回复某个用户，查询被回复用户信息
        if (comment.getReplyToUserId() != null && comment.getReplyToUserId() > 0) {
            User replyToUser = userMapper.selectById(comment.getReplyToUserId());
            if (replyToUser != null) {
                vo.setReplyToUserName(replyToUser.getNickname() != null ? replyToUser.getNickname() : replyToUser.getStudentId());
            }
        }
        
        // 判断当前用户是否已点赞
        if (userId != null) {
            vo.setIsLiked(isCommentLiked(comment.getId(), userId));
        } else {
            vo.setIsLiked(false);
        }
        
        return vo;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void likeComment(Long commentId, Long userId) {
        // 验证评论是否存在
        Comment comment = commentMapper.selectById(commentId);
        if (comment == null || comment.getStatus() != 0) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "评论不存在");
        }
        
        // 检查是否已点赞
        LambdaQueryWrapper<CommentLike> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CommentLike::getCommentId, commentId)
                .eq(CommentLike::getUserId, userId);
        
        Long count = commentLikeMapper.selectCount(wrapper);
        if (count > 0) {
            throw new BusinessException(ResultCode.OPERATION_ERROR, "已经点赞过了");
        }
        
        // 添加点赞记录
        CommentLike commentLike = new CommentLike();
        commentLike.setCommentId(commentId);
        commentLike.setUserId(userId);
        commentLikeMapper.insert(commentLike);
        
        // 增加评论点赞数
        commentMapper.incrementLikeCount(commentId);
        
        log.info("用户{}点赞评论{}成功", userId, commentId);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void unlikeComment(Long commentId, Long userId) {
        // 删除点赞记录
        LambdaQueryWrapper<CommentLike> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CommentLike::getCommentId, commentId)
                .eq(CommentLike::getUserId, userId);
        
        int rows = commentLikeMapper.delete(wrapper);
        if (rows <= 0) {
            throw new BusinessException(ResultCode.OPERATION_ERROR, "未点赞过该评论");
        }
        
        // 减少评论点赞数
        commentMapper.decrementLikeCount(commentId);
        
        log.info("用户{}取消点赞评论{}成功", userId, commentId);
    }
    
    @Override
    public Boolean isCommentLiked(Long commentId, Long userId) {
        if (userId == null) {
            return false;
        }
        
        LambdaQueryWrapper<CommentLike> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CommentLike::getCommentId, commentId)
                .eq(CommentLike::getUserId, userId);
        
        Long count = commentLikeMapper.selectCount(wrapper);
        return count > 0;
    }
}

